<?php

namespace MoChat\App\Statistic\Action\Call;

use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\Middlewares;
use Hyperf\HttpServer\Annotation\RequestMapping;
use MoChat\App\Rbac\Middleware\PermissionMiddleware;
use MoChat\App\Common\Middleware\DashboardAuthMiddleware;
use MoChat\App\Sales\Constants\SalesTaskStatusCode;
use MoChat\App\Sales\Contract\SalesClientTaskContract;
use MoChat\App\Sales\Contract\SalesTaskContract;
use MoChat\App\Sales\Contract\WorkDepartmentContract;
use MoChat\Framework\Action\AbstractAction;
use MoChat\Framework\Constants\ErrorCode;
use MoChat\Framework\Exception\CommonException;
use MoChat\Framework\Request\ValidateSceneTrait;

/**
 * 会员绑定统计列表
 * @Controller
 */
class Index extends AbstractAction
{
    use ValidateSceneTrait;

    /**
     * @Middlewares({
     *     @Middleware(DashboardAuthMiddleware::class),
     *     @Middleware(PermissionMiddleware::class)
     * })
     * @RequestMapping(path="/dashboard/statisticCall/list", methods="GET")
     */
    public function handle()
    {
        $user = user();
        // 判断用户绑定企业信息
        if (!isset($user['corpIds']) || count($user['corpIds']) !== 1) {
            throw new CommonException(ErrorCode::INVALID_PARAMS, '未选择登录企业，不可操作');
        }
        $data = $this->request->all();
        $this->validated($data);
        $list = Db::table('work_employee as employee')
            ->join('user as user', 'user.id', '=', 'employee.log_user_id')
            ->leftJoin('work_department as dept', 'dept.id', '=', 'employee.main_department_id')
            ->leftJoin('call_record as record', 'record.user_id', '=', 'user.id')
            ->when(!empty($data['deptId']), function ($query) use ($data) {
                $query->where('dept.id', $data['deptId']);
            })
            ->when(!empty($data['employeeName']), function ($query) use ($data) {
                $query->where('employee.name', 'like', '%' . $data['employeeName'] . '%');
            })
            ->when(!empty($data['startTime']) && !empty($data['endTime']), function ($query) use ($data) {
                $query->whereBetween('record.created_time', [$data['startTime'], $data['endTime']]);
            })->when(!empty($data['orderBy']),function ($query)use($data){
                $orderString='';
                $data['orderBy']=json_decode($data['orderBy'],true);
                foreach ($data['orderBy'] as $key=>$datum){
                    if ($datum){
                        if ($key=='callOutAnswerRate'){
                            $key='rate';
                        }
                        $datum=$datum=='ascend'?'asc':'desc';
                        $orderString.=$orderString?','.$key.' '.$datum:$key.' '.$datum;
                    }
                }
                if ($orderString){
                    $query->orderByRaw($orderString);
                }
            })
            ->select([
                'employee.id',
                'employee.name',
                'dept.name as deptName',
                'user.extn',
                'record.call_type',
                Db::raw('SUM(mc_record.call_duration) as callDuration'),//总通话数（呼入+呼出）
                Db::raw('COUNT(mc_record.call_duration > 0 or null) as putOnNumber'),//接通数
                Db::raw('COUNT(mc_record.call_duration = 0 or null) as noPutOnNumber'),//未接通数
                Db::raw('COUNT(*) as totalNumber'),//总通话数
                Db::raw('COUNT(mc_record.call_type="out" or null) as callOutNumber'),//呼出总量
                Db::raw('COUNT((mc_record.call_duration > 0 && mc_record.call_type="out") or null) as callOutAnswerNumber'),//呼出接听量
                Db::raw('SUM(if(mc_record.call_type="out",call_duration,0)) as callOutDuration'),//呼出总时长
                Db::raw('SUM(if(mc_record.call_type="in",call_duration,0)) as callInDuration'),//呼入总时长
                Db::raw('COUNT(mc_record.call_type="in" or null) as callInNumber'),//呼入总量
                Db::raw('COUNT((mc_record.call_duration > 0 && mc_record.call_type="in") or null) as callInAnswerNumber'),//呼入接听量
                Db::raw('COUNT((mc_record.call_duration = 0 && mc_record.call_type="out") or null) as missedConnection'),//振铃未接呼出数
                Db::raw('COUNT((mc_record.call_duration > 0 && mc_record.call_type = "out") or null)/ COUNT(mc_record.call_type = "out" or null) as rate')
            ])->groupBy([
                'employee.id'
            ])->paginate();
        $list || $list = collect([]);
        $list = $list->toArray();
        if (!empty($list['data'])) {
            foreach ($list['data'] as &$item) {
                $item->callDuration = is_null($item->callDuration) ? 0 : $item->callDuration;
                $item->extn = is_null($item->extn) ? '' : $item->extn;
                //总接通率
                $item->totalTurnOnRate = $item->totalNumber ? bcmul(bcdiv($item->putOnNumber, $item->totalNumber,10), 100, 2) . '%' : "0%";
                //呼出接听率
                $item->callOutAnswerRate = $item->callOutNumber ? bcmul(bcdiv($item->callOutAnswerNumber, $item->callOutNumber,10), 100, 2) . '%' : "0%";
                //呼入接听率
                $item->callInAnswerRate = $item->callInNumber ? bcmul(bcdiv($item->callInAnswerNumber, $item->callInNumber,10), 100, 2) . '%' : "0%";
            }
            unset($item);
            //总通话数合计
            $list['totalCallSeconds']=array_sum(array_column($list['data'],'callDuration'));
            //呼出总量合计
            $list['totalCallOutNumber']=array_sum(array_column($list['data'],'callOutNumber'));
            // 呼出接听量合计
            $list['totalCallOutAnswerNumber']=array_sum(array_column($list['data'],'callOutAnswerNumber'));
            //  呼出总时长合计
            $list['totalCallOutSeconds']=array_sum(array_column($list['data'],'callOutDuration'));
        }
        return $list;

    }


    /**
     * 验证规则.
     */
    protected function rules(): array
    {
        return [
            'page' => 'required|integer',
        ];
    }

    /**
     * 获取已定义验证规则的错误消息.
     */
    protected function messages(): array
    {
        return [
            'page.required' => '分页参数错误',
            'page.integer' => '分页参数错误',
        ];
    }
}
